package com.wei.czz.framework.rabbitMQ.listener;

import com.wei.czz.common.constant.RedisConstant;
import com.wei.czz.common.enums.rabbitMQ.BlogMessageEnum;
import com.wei.czz.common.enums.rabbitMQ.MqEnum;
import com.wei.czz.framework.blog.service.BlogTagService;
import com.wei.czz.framework.common.handler.redis.RedisStringHandler;
import com.wei.czz.framework.common.handler.redis.RedisZSetHandler;
import com.wei.czz.framework.blog.entity.BlogEntity;
import com.wei.czz.framework.blog.entity.BlogStatsEntity;
import com.wei.czz.framework.blog.service.BlogService;
import com.wei.czz.framework.blog.service.BlogStatsService;
import com.wei.czz.framework.rabbitMQ.message.blog.BlogMessage;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wei
 * date: 2022-02-27 23:24:19
 * className: BlogQueueListener 博客消息队列监听类
 * version: 1.0
 * description:
 */
@Component
@AllArgsConstructor
public class BlogQueueListener {

    private static final Logger log = LoggerFactory.getLogger(BlogQueueListener.class);

    private final BlogService blogService;

    private final BlogTagService blogTagService;

    private final BlogStatsService blogStatsService;

    private final RedisZSetHandler redisZSetHandler;

    private final RedisStringHandler redisStringHandler;

    /**
     * 系统已发布博客关联标签变化消息监听方法
     * 根据博客消息，增加或者减少系统已发布博客关联的标签数量
     * @param blogMessage 博客消息对象
     */
    @RabbitListener(queues = { MqEnum.Queue.BLOG_TAG })
    public void blogTagMessage(BlogMessage blogMessage) {
        log.info("开始根据博客消息异步更新系统已发布博客关联的博客标签数量业务。{}", blogMessage);

        // 查询数据库，获取博客关联的所有标签名称
        List<String> tagNameList = blogTagService.findNameList(blogMessage.getBlogId());

        if (BlogMessageEnum.ADD.getValue().equals(blogMessage.getType())) {
            /*
                增加
             */
            for (String tagName : tagNameList) {
                // 操作Redis缓存，系统已发布博客关联的博客标签数量加一
                redisZSetHandler.incrementScore(RedisConstant.TAG_ZSET, tagName, 1);
            }
        } else {
            /*
                减少
             */
            for (String tagName : tagNameList) {
                // 操作Redis缓存，系统已发布博客关联的博客标签数量减一
                redisZSetHandler.incrementScore(RedisConstant.TAG_ZSET, tagName, -1);
            }

            // 操作Redis缓存，删除已发布博客关联的博客标签次数小于等于零的数据
            redisZSetHandler.removeRangeByScore(RedisConstant.TAG_ZSET, -1, 0);
        }
        log.info("根据博客消息异步更新系统已发布博客关联的博客标签数量业务结束");
    }

    /**
     * 系统博客状态变化消息监听方法
     * 根据博客消息，增加或者减少系统已发布博客的总浏览次数、总点赞数和总评论数
     * @param blogMessage 博客消息对象
     */
    @RabbitListener(queues = { MqEnum.Queue.BLOG_STATUS })
    public void blogUpdateMessage(BlogMessage blogMessage) {
        log.info("开始根据博客消息，异步更新系统博客的浏览次数、点赞数和评论数缓存业务。{}", blogMessage);

        BlogEntity blog = blogService.getBlog(blogMessage.getBlogId());

        BlogStatsEntity blogStats = new BlogStatsEntity();

        // 查询数据库博客统计表，获取博客统计信息
        List<BlogStatsEntity> blogStatsList = blogStatsService.getBlogStatsList(blogMessage.getBlogId());
        if (!blogStatsList.isEmpty()) {
            blogStats = blogStatsList.get(0);
        }

        // 博客id类型转化
        String blogId = blogMessage.getBlogId().toString();

        try {
            if (BlogMessageEnum.ADD.getValue().equals(blogMessage.getType())) {
                /*
                    增加
                 */
                // 操作Redis缓存，增加系统已发布博客的总浏览次数
                redisStringHandler.increment(RedisConstant.VIEW_COUNT, blog.getViewNum());
                // 操作Redis缓存，增加今天的博客浏览次数缓存
                redisZSetHandler.add(RedisConstant.DAY_BLOG_VIEW_ZSET, blogId, blogStats.getDayViewNum());
                // 操作Redis缓存，增加这个月的博客浏览次数缓存
                redisZSetHandler.add(RedisConstant.MONTH_BLOG_VIEW_ZSET, blogId, blogStats.getMonthViewNum());

                // 操作Redis缓存，增加系统已发布博客的总点赞数
                redisStringHandler.increment(RedisConstant.LIKE_COUNT, blog.getLikeNum());

                // 操作Redis缓存，增加系统已发布博客的总评论数
                redisStringHandler.increment(RedisConstant.COMMENT_COUNT, blog.getCommentNum());
            } else {
                /*
                    减少
                 */
                // 操作Redis缓存，减少系统已发布博客的总浏览次数
                redisStringHandler.decrement(RedisConstant.VIEW_COUNT, blog.getViewNum());
                // 操作Redis缓存，删除今天的博客浏览次数缓存
                redisZSetHandler.remove(RedisConstant.DAY_BLOG_VIEW_ZSET, blogId);
                // 操作Redis缓存，删除这个月的博客浏览次数缓存
                redisZSetHandler.remove(RedisConstant.MONTH_BLOG_VIEW_ZSET, blogId);
                // 操作Redis缓存，减少系统已发布博客的总点赞数
                redisStringHandler.decrement(RedisConstant.LIKE_COUNT, blog.getLikeNum());
                // 操作Redis缓存，减少系统已发布博客的总评论数
                redisStringHandler.decrement(RedisConstant.COMMENT_COUNT, blog.getCommentNum());
            }
        } catch (Exception e) {
            log.error("根据博客消息，异步更新系统博客的浏览次数、点赞数和评论数缓存失败，请务必及时处理。message={}", e.getMessage(), e);
        }
        log.info("根据博客消息，异步更新系统博客的浏览次数、点赞数和评论数缓存业务结束");
    }

}
